from setuptools import setup, find_packages, Extension
import importlib
from setuptools.command.build_ext import build_ext
import os.path
import glob
import os
import sys
import platform

"""

IMPORTANT!: this script is only needed to build an extra python module interface for a different python version;
            it has hardcode pathrd to the building directory.
            It is not needed for conda to build package.

This project cmake will detect one default python version and build the interface for it.
All python stuff installation can be done in cmake/cpack's `install()`.


`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"`
while it is not quite pythonic way.


This setup must be run after C++ shared libraries have been compiled by cmake.
c++ runtime *.so/dll must be installed to somwhere loadable (appending LD_LIBRARY_PATH if installed to non-system path)
either by conda or platform installer like deb.rpm/make install

### PyPI upload is yet done
```
cd build/python
python3 setup.py bdist_wheel
rm package.egg-info #  rm folder where the sources.txt(manifest) will not be updated
python3 -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
# for CI, just copy to asset folder
# copy the output package from ./dist to somwhere? to be downloaded, should be done by CI script
```

see a full list of setup.py arguments
https://www.cac.cornell.edu/wiki/index.php?title=Python_Distutils_Tips
python setup.py --help-commands
bdist            create a built (binary) distribution
bdist_rpm        create an RPM distribution
bdist_wininst    create an executable installer for MS Windows

### Todo:
 cmake configure_file()  for macro expansion like version, or read from a version.json generated by cmake

"""

# there is no pure python scripts in this ppp module, just ppp.so, all other python scripts go into bin/
# as deb/rpm/conda has done packing all C++ header and shared libraries, this incompleted function is disabled
packing_dep_lib = False

print("current folder to build the python package: ", os.path.abspath(os.path.curdir))
ppp_package_name = "ppp-py3.{}".format(sys.version_info[1])
# manifast file will be generated from setup.py
#  setup.py also support `build_clib` to build C/C++ libraries used by Python extensions

if platform.system == "Windows":
    ext_suffix = "pyd"
elif platform.system == "Macos":
    ext_suffix = "dylib"
else:
    ext_suffix = "so"
#importlib.machinery.EXTENSION_SUFFIXES  # return list not string!


occt_include_dir = "/usr/include/opencascade"
ppp_include_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# FIXME: it is assume the out source build dir is called "build"
ppp_lib_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + os.path.sep + "build" + os.path.sep + "lib"

# find and pack the cmake built ppp python module, actually it is not needed for this setup.py
if False:
    ext_output_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + os.path.sep + "lib"
    ppp_extensions = glob.glob(ext_output_path + os.path.sep + "ppp*." + ext_suffix)
    print("shipped extension libraries", ppp_extensions)


if packing_dep_lib:

    if platform.system == "Windows":
        so_suffix = "dll"
    elif platform.system == "Macos":
        so_suffix = "dylib"
    else:
        so_suffix = "so"

    app_output_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + os.path.sep + "bin"
    ppp_application = glob.glob(lib_output_path + os.path.sep + "*")  # all files,
    # including python scripts copied by cmake install()
    # todo: python scripts should be make executable?

    lib_output_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + os.path.sep + "lib"
    ppp_libraries = glob.glob(lib_output_path + os.path.sep + "*." + so_suffix)
    # for non-windows platforms, how to ditinguish sharedlib from python ext lib, but list substraction
    ppp_libraries = [f for f in ppp_libraries if f not in ppp_extensions]
    print("shipped shared application", ppp_libraries)

    # sysconfig.get_paths()

# this will do similar thing as the cmake to compile AppPy.cpp, but for a different python version
# https://github.com/pybind/python_example/blob/master/setup.py
ppp_cext = Extension('ppp', ['AppPy.cpp'],
        include_dirs=['pybind11/include', ppp_include_dir, ppp_include_dir+os.path.sep + "third-party", occt_include_dir],
        library_dirs=[ppp_lib_dir],
        libraries=['pppBase', 'pppApp', 'pppGeom'],
        language='c++'
        )


class BuildExt(build_ext):
    """A custom build extension for adding compiler-specific options."""
    c_opts = {
        'msvc': ['/EHsc'],
        'unix': [],
    }
    l_opts = {
        'msvc': [],
        'unix': [],
    }

    if sys.platform == 'darwin':
        darwin_opts = ['-stdlib=libc++', '-mmacosx-version-min=10.7']
        c_opts['unix'] += darwin_opts
        l_opts['unix'] += darwin_opts

    def build_extensions(self):
        ct = self.compiler.compiler_type
        opts = self.c_opts.get(ct, [])
        link_opts = self.l_opts.get(ct, [])
        if ct == 'unix':
            opts.append('-std=c++17')
            #if has_flag(self.compiler, '-fvisibility=hidden'):
            #    opts.append('-fvisibility=hidden')
            opts.append('-fvisibility=hidden')

        for ext in self.extensions:
            ext.define_macros = [('VERSION_INFO', '"{}"'.format(self.distribution.get_version()))]
            ext.extra_compile_args = opts
            ext.extra_link_args = link_opts
        build_ext.build_extensions(self)


kwargs = {
    "name": "parallel-preprocessor",
    "version": "0.3.0",  # todo: get the version info from file written by cmake
    #"packages": ["ppp"],  # find source code folder with __init__.py, find_packages()
    # ext_modules # cpp soruce to build, skip it as cmake will build
    # "license": "TBD",
    "author": "qingfeng xia",
    "author_email": "qingfeng xia@UKAEA",
    "description": "python3 wrap for parallel preprocessor",
    # long_description=long_description,
    # long_description_content_type="text/markdown",
    "url": "https://github.com/pypa/sampleproject",  # todo
    "classifiers": [
        "Programming Language :: Python :: 3",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
        "Operating System :: POSIX",
        "License :: OSI Approved :: LGPL License",
        "Topic :: Science",
        "Topic :: Engineering",
    ],
    "python_requires": ">=3.5",
    # ensure ext-lib-files are copied to the python site:
    #"package_data": {ppp_package_name: ppp_extensions},
    "ext_modules": [ppp_cext],
    "cmdclass": {'build_ext': BuildExt},
    #"include_package_data": True,
    "zip_safe": False,
}

setup(**kwargs)

